/**
 * @file Domain.cpp
 * @author Michael Barriault
 * @version 0.3
 * @date 10-09-23
 * @project T3nsors
 */

#include <T3nsors/Domain.h>
#include <T3nsors/Macros.h>
#include <cstdlib>
#include <cstdarg>

T3::Domain::Domain(void) {
	return;
}

T3::Domain::Domain(int l, ...) {
	va_list vl;
	va_start(vl,l);
	N = l;
	O.assign(N,0);
	r.assign(2*N,0.);
	D.assign(N,0.);
	P.assign(N,0.);
	FOR(i,N) P[i] = 0;
	O[0] = va_arg(vl,int)+1;
	FOR(i,N) {
		r[2*i] = va_arg(vl,real);
		r[2*i+1] = va_arg(vl,real);
	}
	FOR(i,N-1) O[i+1] = (O[0]-1) * (r[2*i+3]-r[2*i+2])/(r[1]-r[0]) + 1;
	FOR(i,N) D[i] = (r[2*i+1]-r[2*i])/(O[i]-1);
	va_end(vl);
	
/*	std::vector<int> Osum(N+1,0);
	FRO(i,1,N+1) Osum[i] = Osum[i-1]+O[i-1];
	_x = Array(Osum[N], "x");
	FOR(a,N) FOR(i,O[a]) _x[Osum[a]+i] = r[2*a] + i*D[a];*/
	return;
}

int T3::Domain::operator()(int i) {
	if ( i == -1 ) return 1;
	return O[i];
}

real T3::Domain::min(void) {
	return r[0];
}

real T3::Domain::min(int i) {
	return r[2*i];
}

real T3::Domain::max(void) {
	return r[1];
}

real T3::Domain::max(int i) {
	return r[2*i+1];
}

real T3::Domain::d(int i) {
	return D[i];
}

real T3::Domain::d(void) {
	return d(0);
}

real& T3::Domain::p(int i) {
	return P[i];
}

T3::Domain Merge(T3::Domain O, T3::Domain P) {
	T3::Domain Q = ( O() > P() ) ? O : P;
	return Q;
}

void CheckDims(int m, int n) {
	if ( m != n )
		exit(-1);
}

void CheckDims(T3::Domain O, T3::Domain P) {
//	printf("CheckDims still being used?\n");
	if ( O() != P() )
		exit(-1);
}
